209. 长度最小的子数组

LeetCode 原题链接

image.png

实现思路

  • 该题可以使用滑动窗口的方法来解决。定义两个指针 left 和 right,分别表示当前窗口的左右边界。
  • 右指针不断向右移动,累加窗口内的元素和,当窗口内的元素和大于等于 target 时,记录当前窗口的长度,并尝试通过移动左指针来缩小窗口,缩小的时候需要不断减去左指针指向的元素,直到窗口内的元素和小于 target。
  • 在这个过程中,记录满足条件的最小窗口长度,最后返回结果。如果没有找到满足条件的窗口,则返回 0。
TIP

滑动窗口的特点:两边从同一点开始,右边不断向右移动,直到满足条件,记录窗口长度后,左边开始向右移动,直到不满足条件,再继续右边向右移动,如此循环。

代码实现

var minSubArrayLen = function (target, nums) {
  // 定义左指针
  let left = 0;

  // sum 用来记录当前窗口内的元素和
  let sum = 0;

  // ans 用来记录满足条件的最小窗口长度
  let ans = Number.MAX_VALUE;

  // 右指针不断向右移动,扩大窗口
  for (let right = 0; right < nums.length; right++) {
    // 将当前元素加入窗口内的和
    sum += nums[right];

    // 当窗口内的元素和大于等于 target 时,尝试缩小窗口
    while (sum >= target) {
      // 记录当前窗口的长度,并更新最小长度
      ans = Math.min(ans, right - left + 1);
      // 将左指针指向的元素从窗口内的和中减去,缩小窗口
      sum -= nums[left];
      // 移动左指针,继续尝试缩小窗口
      left++;
    }
  }

  // 
  return ans === Number.MAX_VALUE ? 0 : ans;
};